<template>
  <div>
    <el-row :gutter="20">
      <!-- 模块搜索 -->
      <el-col :span="6" :xs="24">
        <div>
          <el-input
            v-model="nodeName"
            placeholder="请输入过滤条件"
            clearable
            prefix-icon="Search"
          />
        </div>
        <div>
          <el-tree
            ref="scriptTreeRef"
            class="tree-border"
            :data="caseOptions"
            :props="{ label: 'number', children: 'children' }"
            :expand-on-click-node="true"
            :filter-node-method="filterNode"
            node-key="id"
            highlight-current
            default-expand-all
            empty-text="加载中，请稍候"
            @node-click="handleNodeClick"
          >
            <!-- 添加自定义节点内容 -->
            <template #default="{ node, data }">
              <svg-icon :icon-class="getNodeIconClass(data)" />
              <span class="el-tree-node__label">{{
                node.label.toLowerCase()
              }}</span>
            </template>
          </el-tree>
        </div>
      </el-col>
      <el-col :span="18" :xs="24">
        <div>
          <el-button
            v-if="nodeType === NODE_TYPES.TESTCASE"
            @click="toggleScriptTemplate"
            >模板</el-button
          >
          <el-button
            v-if="nodeType === NODE_TYPES.ROOT"
            @click="toggleScriptImport"
            >导入</el-button
          >
          <el-button
            v-if="[NODE_TYPES.ROOT, NODE_TYPES.MODULE].includes(nodeType)"
            @click="toggleScriptExport"
            >导出</el-button
          >
          <el-button @click="toggleScriptEdit">{{ editButtonText }}</el-button>
          <el-button @click="toggleScriptSave">保存</el-button>
          <span style="float: right">{{ scriptName }}</span>
        </div>
        <div style="margin-top: 5px">
          <y-code-editor
            ref="editorRef"
            v-model="form.script"
            language="python"
            :readOnly="readOnly"
            style="height: 600px"
          />
        </div>
      </el-col>
    </el-row>
    <import-export
      :operate="operate"
      :product="product"
      :module="module"
      v-model="openImportExport"
      :title="titleImportExport"
      @close="openImportExport = false"
    />
  </div>
</template>

<script setup>
import { getProduct, updateProduct } from "@/api/pms/product";
import { getModule, updateModule, treeselect } from "@/api/pms/module";
import { getTestCase, updateTestCase, getTemplate } from "@/api/tms/testcase";
import ImportExport from "./components/ImportExport";

const route = useRoute();
const { proxy } = getCurrentInstance();

const form = ref({});
const nodeName = ref("");
const nodeType = ref("Module");
const scriptName = ref("");
const caseOptions = ref([]);
const readOnly = ref(true);
const product = ref(undefined);
const module = ref(undefined);
const operate = ref("import");
const titleImportExport = ref("");
const openImportExport = ref(false);

const NODE_TYPES = {
  ROOT: "Root",
  MAIN: "Main",
  MODULE: "Module",
  CONFTEST: "ConfTest",
  TESTCASE: "TestCase",
};

/** 通过条件过滤节点 */
const filterNode = (value, data) => !value || data.name.includes(value);

const editButtonText = computed(() => (readOnly.value ? "编辑" : "只读"));

/** 根据名称筛选模块树 */
watch(nodeName, (val) => {
  proxy.$refs.scriptTreeRef.filter(val);
});

/** 查询模块下拉树结构 */
async function getCasesTreeNode() {
  try {
    const response = await treeselect({
      product: route.params.id,
      showcase: true,
    });
    processTreeData(response.data);
  } catch (error) {
    console.error("Failed to fetch tree node:", error.message);
  }
}

/** 转换树节点 */
function processTreeData(treeNodes) {
  addConftestToNonLeafNodes(treeNodes);
  const rootTreeNode = {
    id: route.params.id,
    number: "project",
    type: NODE_TYPES.ROOT,
    children: treeNodes,
  };
  rootTreeNode.children.push({
    id: route.params.id,
    number: "main",
    type: NODE_TYPES.MAIN,
  });
  caseOptions.value.push(rootTreeNode);
  if (caseOptions.value.length > 0) {
    handleNodeClick(caseOptions.value[0]);
  }
}

/** 节点单击事件 */
async function handleNodeClick(node) {
  try {
    nodeType.value = node.type;
    if (nodeType.value === NODE_TYPES.ROOT) {
      product.value = node.id;
    } else if (nodeType.value === NODE_TYPES.MAIN) {
      scriptName.value = node.number.toLowerCase() + ".py";
      const response = await getProduct(node.id);
      form.value = response.data;
    } else if (nodeType.value === NODE_TYPES.MODULE) {
      module.value = node.id;
    } else if (nodeType.value === NODE_TYPES.CONFTEST) {
      scriptName.value = node.number.toLowerCase() + ".py";
      const response = await getModule(node.id);
      form.value = response.data;
    } else {
      scriptName.value = node.number.toLowerCase() + ".py";
      const response = await getTestCase(node.id);
      form.value = response.data;
    }
  } catch (error) {
    console.error(`Failed to fetch ${node.type}:`, error.message);
  }
}

/** 添加叶子节点 */
function addConftestToNonLeafNodes(nodes) {
  nodes.forEach((node) => {
    if (node.type == NODE_TYPES.MODULE) {
      node.children.push({
        id: node.id,
        number: "conftest",
        type: NODE_TYPES.CONFTEST,
      });
      addConftestToNonLeafNodes(node.children);
    }
  });
}

/** 根据树节点类型获取树节点图标名称 */
function getNodeIconClass(node) {
  if (node.type === NODE_TYPES.ROOT) {
    return "home";
  } else if (node.type === NODE_TYPES.MODULE) {
    return "folder";
  } else {
    return "code";
  }
}

/** 脚本导入事件 */
function toggleScriptImport() {
  operate.value = "import";
  openImportExport.value = true;
  titleImportExport.value = "脚本导入";
}

/** 脚本导出事件 */
function toggleScriptExport() {
  operate.value = "export";
  openImportExport.value = true;
  titleImportExport.value = "脚本导出";
}

/** 脚本编辑事件 */
function toggleScriptEdit() {
  readOnly.value = !readOnly.value;
}

/** 脚本模板事件 */
function toggleScriptTemplate() {
  getTemplate(form.value.id).then((response) => {
    form.value.script = response.data;
  });
}

/** 脚本保存事件 */
function toggleScriptSave() {
  if (!form.value) return;

  const updateFnMap = {
    [NODE_TYPES.MAIN]: updateProduct,
    [NODE_TYPES.CONFTEST]: updateModule,
    [NODE_TYPES.TESTCASE]: updateTestCase,
  };

  const updateFn = updateFnMap[nodeType.value];
  if (!updateFn) return;

  updateFn(form.value).then((res) => {
    proxy.$modal.msgSuccess("保存成功");
  });
}

onMounted(getCasesTreeNode);
</script>
